Освоить жизненный цикл объекта на С++ — значит полностью овладеть самой механикой его существования в куче и стеке. Управление копированием определяет, как класс управляет своим жизненным циклом с помощью двух операций: конструктор копирования и конструктор копирования и оператор присваивания копии.
1. Инициализация против присваивания
Прямая инициализация (например, string dots(10, '.')) напрямую вызывает конструктор. Однако инициализация копированием (string s2 = dots) зависит от конструктора копирования. В отличие от инициализации, присваивание (trans = accum) перезаписывает существующий объект с помощью оператора =. Критическое ограничение: параметр конструктора копирования должен быть ссылкой (const Foo&); в противном случае передача аргумента по значению вызовет бесконечную рекурсивную петлю вызовов копирования.
2. Роль синтеза
Если вы не определите эти члены, компилятор предоставит синтезированные версии, которые выполняют копирование по элементам. Остерегайтесь: хотя для простых типов они достаточны, часто они не работают для классов, управляющих динамической памятью, что приводит к висячим указателям или двойным освобождениям памяти.